﻿using Autofac;
using Autofac.Extensions.DependencyInjection;
using WPay.Application.Base;
using WPay.Domain.Base;
using WPay.Infrastructure.Unity;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using CommonUtility;

namespace WPay.Infrastructure.IOC
{
    public static class IOCService
    {
        /// <summary>
        /// 依赖注入
        /// </summary>
        /// <param name="service"></param>
        /// <returns></returns>
        public static IServiceCollection RegisterAssembly(this IServiceCollection service)
        {
            //注册上下文
            service.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

            RegisterAssembly(service, typeof(IApplication_IocServices));
            RegisterAssembly(service, typeof(IDomain_IocServices));
            RegisterAssembly(service, typeof(IRepository_IocServices));
            return service;
        }
        private static void RegisterAssembly(this IServiceCollection service, System.Type interfaceType)
        {

            AssemblyHelper.GetAllAssemblies().ForEach(interfaceAssembly =>
            {
                var _interfaceType = interfaceAssembly.GetTypes().Where(t =>
                    t.GetTypeInfo().IsInterface && !t.GetTypeInfo().IsGenericType &&
                    t.GetInterfaces().Contains(interfaceType));

                foreach (var type in _interfaceType)
                {
                    var implementTypeName = type.Name.Substring(1);
                    var implementType = AssemblyHelper.GetImplementType(implementTypeName, type);
                    //LoggerHelper.Log(implementTypeName + "---" + implementType);
                    if (implementType != null)
                    {
                        /**
                         *  services.AddSingleton 生命周期为：单例（也叫全局单例，在整个应用生命周期里，都只创建一次）
                         *  services.AddTransient 生命周期为：瞬时（每次从服务容器中请求实例时都会创建一个全新的实例，每次都new一个）
                         *  services.AddScoped 生命周期为：作用域（在同一个线程（请求）里，只实例化一次）
                         */
                        service.AddTransient(type, implementType);
                    }
                }
            });
        }
        /// <summary>
        /// 依赖注入
        /// </summary>
        /// <param name="service"></param>
        /// <returns></returns>
        public static IServiceProvider RegisterAssembly()
        {
            ////创建一个依赖注入容器（IServiceProvider）
            var service = new ServiceCollection();
            //注册上下文
            RegisterAssembly(service, typeof(IApplication_IocServices));
            RegisterAssembly(service, typeof(IDomain_IocServices));
            RegisterAssembly(service, typeof(IRepository_IocServices));
            return service.BuildServiceProvider().CreateScope().ServiceProvider;
        }
        private static void RegisterAssembly(ServiceCollection service, System.Type interfaceType)
        {

            AssemblyHelper.GetAllAssemblies().ForEach(interfaceAssembly =>
            {
                var _interfaceType = interfaceAssembly.GetTypes().Where(t =>
                    t.GetTypeInfo().IsInterface && !t.GetTypeInfo().IsGenericType &&
                    t.GetInterfaces().Contains(interfaceType));

                foreach (var type in _interfaceType)
                {
                    var implementTypeName = type.Name.Substring(1);
                    var implementType = AssemblyHelper.GetImplementType(implementTypeName, type);
                    if (implementType != null)
                    {
                        /**
                         *  services.AddSingleton 生命周期为：单例（也叫全局单例，在整个应用生命周期里，都只创建一次）
                         *  services.AddTransient 生命周期为：瞬时（每次从服务容器中请求实例时都会创建一个全新的实例，每次都new一个）
                         *  services.AddScoped 生命周期为：作用域（在同一个线程（请求）里，只实例化一次）
                         */
                        service.AddScoped(type, implementType);
                    }
                }
            });
        }

    }
}
